<?php

/**
 * This file is part of the Framework03 PHP framework.
 * @author Walter Tamboer
 * @package Framework03
 */

class FW_Database_Adapter_MySQL extends FW_Database_Adapter_Abstract
{
    /**
     * @var resource The connection handle.
     */
    private $handle = null;

    /**
     * Initializes a new instance of this class.
     * @param array|FW_Config $options Optional options for this database adapter.
     */
    public function __construct($options = null)
    {
        if (!extension_loaded('mysql'))
            throw new FW_Database_Adapter_MySQL_Exception("MySQL extension isn't loaded.", 500);

        $this->setOptions(array(
            'host' => 'localhost',
            'port' => 3306,
            'username' => '',
            'password' => '',
            'dbname' => ''
            ));

        parent::__construct($options);
    }

    /**
     * Creates a connection with the database.
     */
    public function connect()
    {
        $this->handle = @mysql_connect(
            $this->getHost() . ':' . $this->getPort(),
            $this->getUsername(),
            $this->getPassword());

		if (mysql_errno())
			throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());

        @mysql_select_db($this->getDatabaseName(), $this->handle);

		if (mysql_errno())
			throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());
    }

    /**
     * Destroys the current connection with the database.
     */
    public function disconnect()
    {
        @mysql_close($this->handle);
    }

    /**
     * Executes the given database statement.
     * @param FW_Database_Statement_Abstract $statement
     * @return FW_Database_Adapter_Abstract|FW_Database_Adapter_Rowset
     */
    public function execute(FW_Database_Statement_Abstract $statement)
    {
        if ($statement instanceof FW_Database_Statement_Select)
        {
            $columns = $statement->getColumns();

            // It is possible that no columns have been set, in that case we want to select everything.
            if (count($columns) > 0)
            {
                $newColumns = array();
                
                foreach ($columns as $name => $as)
                {
                    if (is_string($name))
                        $newColumns[] = $name . ' AS ' . $as;
                    else
                        $newColumns[] = $as;
                }


                $columns = $newColumns;
            }
            else
                $columns = array('*');

            $query = "SELECT " . implode(',', $columns) . " FROM " . $statement->getTableName();
            $result = @mysql_query($query, $this->handle);

            if (!$result)
                throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());

            return new FW_Database_Adapter_MySQL_Rowset($this, $result);
        }
        else if ($statement instanceof FW_Database_Statement_Insert)
        {
            $columns = $statement->getColumnNames();
            $values = $statement->getColumnValues();

            if (count($columns) < 1)
                throw new FW_Database_Adapter_MySQL_Exception('No columns found to insert data in.');

            if (count($columns) != count($values))
                throw new FW_Database_Adapter_MySQL_Exception('Values and columns don\'t match.');

            $query = "INSERT INTO " . $statement->getTableName() .
                     " (" . implode(', ', $columns) . ") VALUES ('" . implode("', '", $values) . "')";

            $result = @mysql_query($query, $this->handle);

            if (!$result)
                throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());
        }
        else if ($statement instanceof FW_Database_Statement_Truncate)
        {
            $query = "TRUNCATE " . $statement->getTableName();
            $result = @mysql_query($query, $this->handle);

            if (!$result)
                throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());
        }
        else if ($statement instanceof FW_Database_Statement_DropTable)
        {
            $query = "DROP TABLE " . $statement->getTableName();
            $result = @mysql_query($query, $this->handle);

            if (!$result)
                throw new FW_Database_Adapter_MySQL_Exception(mysql_error(), mysql_errno());
        }
        else
            throw new FW_Database_Adapter_MySQL_Exception('Unknown database statement given.', 500);

        return $this;
    }
}
